home *** CD-ROM | disk | FTP | other *** search
/ Amiga Format CD 41 / Amiga Format CD41 (1999-06)(Future Publishing)(GB)[!][issue 1999-07].iso / -seriously_amiga- / programming / other / gtlayout / source / ltp_find.c < prev    next >
C/C++ Source or Header  |  1999-04-19  |  4KB  |  248 lines

  1. /*
  2. **    GadTools layout toolkit
  3. **
  4. **    Copyright © 1993-1998 by Olaf `Olsen' Barthel
  5. **        Freely distributable.
  6. **
  7. **    :ts=4
  8. */
  9.  
  10. #ifndef _GTLAYOUT_GLOBAL_H
  11. #include "gtlayout_global.h"
  12. #endif
  13.  
  14. #include "Assert.h"
  15.  
  16. LONG
  17. LTP_Find_Clicked_Item(LayoutHandle *handle,ObjectNode *radio,LONG x,LONG y)
  18. {
  19.     if(x >= radio->Left + INTERWIDTH)
  20.     {
  21.         LONG i,top = radio->Top,height,single;
  22.  
  23.         height = ((radio->Height + handle->InterHeight) / radio->Lines);
  24.         single = height - handle->InterHeight;
  25.  
  26.         for(i = 0 ; i <= radio->Max ; i++)
  27.         {
  28.             if(y >= top && y < top + single)
  29.                 return(i);
  30.             else
  31.                 top += height;
  32.         }
  33.     }
  34.  
  35.     return(-1);
  36. }
  37.  
  38.  
  39. /*****************************************************************************/
  40.  
  41.  
  42. ObjectNode *
  43. LTP_FindNode_Position(ObjectNode *group,LONG x,LONG y)
  44. {
  45.     ObjectNode    *node;
  46.     ULONG         page;
  47.  
  48.     SCANPAGE(group,node,page)
  49.     {
  50.         if(node->Type == GROUP_KIND)
  51.         {
  52.             ObjectNode *result;
  53.  
  54.             if(result = LTP_FindNode_Position(node,x,y))
  55.                 return(result);
  56.             else
  57.             {
  58.                 if(node->Top <= y && node->Top + node->Height > y && node->Left <= x && node->Left + node->Width > x)
  59.                 {
  60.                     while(node)
  61.                     {
  62.                         if(node->ID <= PHANTOM_GROUP_ID)
  63.                             node = node->Special.Group.ParentGroup;
  64.                         else
  65.                             return(node);
  66.                     }
  67.  
  68.                     return(NULL);
  69.                 }
  70.             }
  71.         }
  72.         else
  73.         {
  74.             if(node->Top <= y && node->Top + node->Height > y)
  75.             {
  76.                 switch(node->Type)
  77.                 {
  78.                     case CHECKBOX_KIND:
  79.  
  80.                         if(node->LabelPlace == PLACE_LEFT)
  81.                         {
  82.                             if(node->Left - (node->LabelWidth + INTERWIDTH) <= x && node->Left - INTERWIDTH > x)
  83.                                 return(node);
  84.                         }
  85.                         else
  86.                         {
  87.                             if(node->Left + node->Width + INTERWIDTH <= x && node->Left + node->Width + INTERWIDTH + node->LabelWidth > x)
  88.                                 return(node);
  89.                         }
  90.  
  91.                         break;
  92.  
  93.                     case MX_KIND:
  94.  
  95.                         if(node->Left + node->Width + INTERWIDTH <= x && node->Left + node->Width + INTERWIDTH + node->Special.Radio.LabelWidth > x)
  96.                             return(node);
  97.  
  98.                         break;
  99.  
  100.                     default:
  101.  
  102.                         if(node->Left <= x && node->Left + node->Width > x)
  103.                         {
  104.                             switch(node->Type)
  105.                             {
  106.                                 case PICKER_KIND:
  107.  
  108.                                     return(node->Special.Picker.Parent->UserData);
  109.  
  110.                                 case INCREMENTER_KIND:
  111.  
  112.                                     return(node->Special.Incrementer.Parent->UserData);
  113.  
  114.                                 default:
  115.  
  116.                                     return(node);
  117.                             }
  118.                         }
  119.                 }
  120.             }
  121.         }
  122.     }
  123.  
  124.     return(NULL);
  125. }
  126.  
  127.  
  128. /*****************************************************************************/
  129.  
  130. STATIC ObjectNode *
  131. LTP_FindGroupNode(ObjectNode *group,LONG id)
  132. {
  133.     ObjectNode *node;
  134.     ObjectNode *result;
  135.  
  136.     SCANGROUP(group,node)
  137.     {
  138.         switch(node->Type)
  139.         {
  140.             case INCREMENTER_KIND:
  141.             case PICKER_KIND:
  142.  
  143.                 break;
  144.  
  145.             case GROUP_KIND:
  146.  
  147.                 if(node->ID == id)
  148.                     return(node);
  149.                 else
  150.                 {
  151.                     if(result = LTP_FindGroupNode(node,id))
  152.                         return(result);
  153.                 }
  154.  
  155.                 break;
  156.  
  157.             default:
  158.  
  159.                 if(node->ID == id)
  160.                     return(node);
  161.         }
  162.     }
  163.  
  164.     return(NULL);
  165. }
  166.  
  167. ObjectNode *
  168. LTP_FindNode(LayoutHandle *handle,LONG id)
  169. {
  170.     return(LTP_FindGroupNode(handle->TopGroup,id));
  171. }
  172.  
  173. /*****************************************************************************/
  174.  
  175.     // This is the new and improved gadget search routine. It now does a
  176.     // binary search rather than the linear search it used to do. Works
  177.     // much better with large number of gadgets, but requires the gadget
  178.     // pointers to be sorted in the order of the GadgetID entries.
  179.  
  180. struct Gadget *
  181. LTP_FindGadget(LayoutHandle *handle,LONG id)
  182. {
  183.     if(handle->GadgetArray)
  184.     {
  185.         struct Gadget **Tab;
  186.         LONG Left,Mid,Right;
  187.  
  188.         Tab        = handle->GadgetArray;
  189.         Left    = 0;
  190.         Right    = handle->Index - 1;
  191.  
  192.         do
  193.         {
  194.             Mid = (Left + Right) / 2;
  195.  
  196.             if(id < Tab[Mid]->GadgetID)
  197.                 Right    = Mid - 1;
  198.             else
  199.                 Left    = Mid + 1;
  200.         }
  201.         while(id != Tab[Mid]->GadgetID && Left <= Right);
  202.  
  203.         if(id == Tab[Mid]->GadgetID)
  204.         {
  205.             ObjectNode *node;
  206.             struct Gadget *g;
  207.  
  208.             g = Tab[Mid];
  209.  
  210.             if(node = (ObjectNode *)g->UserData)
  211.             {
  212.                 if(node->PointBack == node && node->Host == g)
  213.                     return(g);
  214.             }
  215.         }
  216.     }
  217.  
  218.     return(NULL);
  219. }
  220.  
  221. struct Gadget *
  222. LTP_FindGadgetLinear(LayoutHandle *handle,LONG id)
  223. {
  224.     if(handle->GadgetArray)
  225.     {
  226.         LONG i;
  227.  
  228.         for(i = 0 ; i < handle->Index ; i++)
  229.         {
  230.             if(handle->GadgetArray[i]->GadgetID == id)
  231.             {
  232.                 ObjectNode *node;
  233.                 struct Gadget *g;
  234.  
  235.                 g = handle->GadgetArray[i];
  236.  
  237.                 if(node = (ObjectNode *)g->UserData)
  238.                 {
  239.                     if(node->PointBack == node && node->Host == g)
  240.                         return(g);
  241.                 }
  242.             }
  243.         }
  244.     }
  245.  
  246.     return(NULL);
  247. }
  248.